/**
 * @file bull_hal_adapter.h
 * @brief 
 * @author yejing (yejh@gongniu.cn)
 * @version 1.0
 * @date 2024-05-09
 * 
 * Copyright 2021-2023 GongNiu Inc. All Rights Reserved.
 * 
 */

#ifndef BULL_HAL_ADAPTER_H
#define BULL_HAL_ADAPTER_H
#include <time.h>
#include <sys/time.h>
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <inttypes.h>
#include "bull_hal_types.h"
#include "bull_hal_error_code.h"
#include "bull_hal_config.h"
#ifdef __cplusplus
extern "C" {
#endif


/*************************pin adapyer**************************/
typedef enum {
    BULL_GPIO_NUM_NC = -1,    /*!< Use to signal not connected to S/W */
    BULL_GPIO_NUM_0 = 0,     /*!< GPIO0, input and output */
    BULL_GPIO_NUM_1 = 1,     /*!< GPIO1, input and output */
    BULL_GPIO_NUM_2 = 2,     /*!< GPIO2, input and output */
    BULL_GPIO_NUM_3 = 3,     /*!< GPIO3, input and output */
    BULL_GPIO_NUM_4 = 4,     /*!< GPIO4, input and output */
    BULL_GPIO_NUM_5 = 5,     /*!< GPIO5, input and output */
    BULL_GPIO_NUM_6 = 6,     /*!< GPIO6, input and output */
    BULL_GPIO_NUM_7 = 7,     /*!< GPIO7, input and output */
    BULL_GPIO_NUM_8 = 8,     /*!< GPIO8, input and output */
    BULL_GPIO_NUM_9 = 9,     /*!< GPIO9, input and output */
    BULL_GPIO_NUM_10 = 10,   /*!< GPIO10, input and output */
    BULL_GPIO_NUM_11 = 11,   /*!< GPIO11, input and output */
    BULL_GPIO_NUM_12 = 12,   /*!< GPIO12, input and output */
    BULL_GPIO_NUM_13 = 13,   /*!< GPIO13, input and output */
    BULL_GPIO_NUM_14 = 14,   /*!< GPIO14, input and output */
    BULL_GPIO_NUM_15 = 15,   /*!< GPIO15, input and output */
    BULL_GPIO_NUM_16 = 16,   /*!< GPIO16, input and output */
    BULL_GPIO_NUM_17 = 17,   /*!< GPIO17, input and output */
    BULL_GPIO_NUM_18 = 18,   /*!< GPIO18, input and output */
    BULL_GPIO_NUM_19 = 19,   /*!< GPIO19, input and output */
    BULL_GPIO_NUM_20 = 20,   /*!< GPIO20, input and output */
    BULL_GPIO_NUM_21 = 21,   /*!< GPIO21, input and output */
    BULL_GPIO_NUM_26 = 26,   /*!< GPIO26, input and output */
    BULL_GPIO_NUM_27 = 27,   /*!< GPIO27, input and output */
    BULL_GPIO_NUM_28 = 28,   /*!< GPIO28, input and output */
    BULL_GPIO_NUM_29 = 29,   /*!< GPIO29, input and output */
    BULL_GPIO_NUM_30 = 30,   /*!< GPIO30, input and output */
    BULL_GPIO_NUM_31 = 31,   /*!< GPIO31, input and output */
    BULL_GPIO_NUM_32 = 32,   /*!< GPIO32, input and output */
    BULL_GPIO_NUM_33 = 33,   /*!< GPIO33, input and output */
    BULL_GPIO_NUM_34 = 34,   /*!< GPIO34, input and output */
    BULL_GPIO_NUM_35 = 35,   /*!< GPIO35, input and output */
    BULL_GPIO_NUM_36 = 36,   /*!< GPIO36, input and output */
    BULL_GPIO_NUM_37 = 37,   /*!< GPIO37, input and output */
    BULL_GPIO_NUM_38 = 38,   /*!< GPIO38, input and output */
    BULL_GPIO_NUM_39 = 39,   /*!< GPIO39, input and output */
    BULL_GPIO_NUM_40 = 40,   /*!< GPIO40, input and output */
    BULL_GPIO_NUM_41 = 41,   /*!< GPIO41, input and output */
    BULL_GPIO_NUM_42 = 42,   /*!< GPIO42, input and output */
    BULL_GPIO_NUM_43 = 43,   /*!< GPIO43, input and output */
    BULL_GPIO_NUM_44 = 44,   /*!< GPIO44, input and output */
    BULL_GPIO_NUM_45 = 45,   /*!< GPIO45, input and output */
    BULL_GPIO_NUM_46 = 46,   /*!< GPIO46, input mode only */
    BULL_GPIO_NUM_47 = 47,   /*!< GPIO46, input mode only */
    BULL_GPIO_NUM_48 = 48,   /*!< GPIO46, input mode only */
    BULL_GPIO_NUM_MAX,
/** @endcond */
}BULL_PIN_NAME_t;

typedef enum {
    BULL_INTR_DISABLE = 0,     /*!< Disable GPIO interrupt                             */
    BULL_INTR_POSEDGE = 1,     /*!< GPIO interrupt type : rising edge                  */
    BULL_INTR_NEGEDGE = 2,     /*!< GPIO interrupt type : falling edge                 */
    BULL_INTR_ANYEDGE = 3,     /*!< GPIO interrupt type : both rising and falling edge */
    BULL_INTR_LOW_LEVEL = 4,   /*!< GPIO interrupt type : input low level trigger      */
    BULL_INTR_HIGH_LEVEL = 5,  /*!< GPIO interrupt type : input high level trigger     */
    BULL_INTR_MAX,
}BULL_IRQ_MODE_T;

typedef enum {
    BULL_PIN_DISABLE = 0,          /*!< GPIO mode : disable input and output             */
    BULL_PIN_INPUT ,              /*!< GPIO mode : input only                           */
    BULL_PIN_OUTPUT ,            /*!< GPIO mode : output only mode                     */
    BULL_PIN_OUTPUT_OD ,       /*!< GPIO mode : output only with open-drain mode     */
    BULL_PIN_INPUT_OUTPUT_OD , /*!< GPIO mode : output and input with open-drain mode*/
    BULL_PIN_INPUT_OUTPUT ,  
} BULL_PIN_MODE_T;

typedef enum
{
    PIN_ACTIVE_LOW,
    PIN_ACTIVE_HIGH,
    PIN_ACTIVE_NONE
}BULL_PIN_ACTIVE_T;

typedef void (*BULL_PIN_IRQ_CB)(void *args);



typedef struct {
    BULL_PIN_NAME_t    gpio;
	BULL_PIN_IRQ_CB    cb;
} BULL_PIN_DEV_MAP_T;

typedef enum {
    BULL_PIN_LOW  = 0,
    BULL_PIN_HIGH
} BULL_PIN_LEVEL_t;

typedef struct {
    int   (*init)       (BULL_PIN_NAME_t pin, BULL_PIN_MODE_T mode, BULL_PIN_ACTIVE_T pin_active, BULL_IRQ_MODE_T irq_mode, BULL_PIN_IRQ_CB irq_cb);
    int   (*write)      (BULL_PIN_NAME_t pin, BULL_PIN_LEVEL_t  level);
    int   (*read)       (BULL_PIN_NAME_t pin);
    int   (*toggle)     (BULL_PIN_NAME_t pin);
    int   (*pin_reset)  (BULL_PIN_NAME_t pin);
} GN_PIN_INIF;


/********************************************************************************
 *********************************bull_hal_sys_system_intf****************************
 ********************************************************************************/

#if OPERATING_SYSTEM == SYSTEM_LINUX
typedef UINT64_T SYS_TICK_T;
#else
typedef UINT_T SYS_TICK_T;
#endif

// typedef struct {
//     int tm_sec;     /* seconds [0-59] */
//     int tm_min;     /* minutes [0-59] */
//     int tm_hour;    /* hours [0-23] */
//     int tm_mday;    /* day of the month [1-31] */
//     int tm_mon;     /* month [0-11] */
//     int tm_year;    /* year. The number of years since 1900 */
//     int tm_wday;    /* day of the week [0-6] 0-Sunday...6-Saturday */
// }BULL_TM_S;
typedef struct tm BULL_TM_S;
typedef enum {
	BULL_RST_POWER_OFF = 0,
    BULL_RST_POWER_ON,
	BULL_RST_HARDWARE_WATCHDOG,
	BULL_RST_FATAL_EXCEPTION,
	BULL_RST_SOFTWARE_WATCHDOG,
	BULL_RST_SOFTWARE,
	BULL_RST_DEEPSLEEP,
	BULL_RST_HARDWARE,
	BULL_RST_OTHER = 0xAA,
	BULL_RST_UNSUPPORT = 0xFF,
} BULL_RST_REASON_E;


typedef struct {
    SYS_TICK_T      (*get_systemtickcount)    (void);
} BULL_HAL_SYS_SYSTEM_INTF;



/********************************************************************************
 *********************************bull_hal_sys_queue_intf****************************
********************************************************************************/

#define BULL_HAL_SYS_QUEUE_FOREVER 0xffffffff
 
typedef void* QUEUE_HANDLE;


/********************************************************************************
 *********************************bull_hal_sys_semaphore_intf*************************
 ********************************************************************************/
typedef void* SEM_HANDLE;
#define BULL_HAL_SYS_SEM_FOREVER 0xFFFFffff



/********************************************************************************
 *********************************bull_hal_sys_thread_intf****************************
 ********************************************************************************/
typedef void* THREAD_HANDLE;
typedef void (*THREAD_FUNC_T)(void*);

typedef enum {
    BULL_TASK_PRIO_0=5,
    BULL_TASK_PRIO_1,
    BULL_TASK_PRIO_2,
    BULL_TASK_PRIO_3,
    BULL_TASK_PRIO_4,
    BULL_TASK_PRIO_5,
    BULL_TASK_PRIO_6,
    BULL_TASK_PRIO_7,
    BULL_TASK_PRIO_8,
    BULL_TASK_MAX_PRIO,
} BULL_TASK_PRIORITY_E;

/********************************************************************************
 *********************************bull_hal_sys_mutex_intf*****************************
 ********************************************************************************/
typedef void* MUTEX_HANDLE;


/********************************************************************************
 *********************************bull_hal_sys_timer_intf********************************
 ********************************************************************************/
typedef void*           TIMER_HANDLE;
typedef void*           TIMER_ID;
typedef void (*TimerCallBack)(TIMER_HANDLE timerCtx);

typedef struct {
    TIMER_ID timerid;          /*timer ID*/
    bool_t autoreload;         /* auto reload ? */
    int period_msecond;        /* timer period by millisecond */
    char *timername;           /* timer name */
    TimerCallBack timeout_cb;  /*timeout callback*/
    TIMER_HANDLE  timer_handle; /*timer handle*/
}bull_timer_param_t;


/********************************************************************************
 *********************************bull_hal_network_intf***************************
 ********************************************************************************/

//the MAC addr len
#define BULL_MAC_ADDR_LEN 6


typedef struct
{
    char ip[16];    /* ip addr:  xxx.xxx.xxx.xxx  */
    char mask[16];  /* net mask: xxx.xxx.xxx.xxx  */
    char gw[16];    /* gateway:  xxx.xxx.xxx.xxx  */
}NW_IP_S;

typedef struct
{
    uint8_t mac[BULL_MAC_ADDR_LEN]; /* mac address */
}NW_MAC_S;

/********************************************************************************
 *********************************bull_hal_sys_wifi_intf******************************
 ********************************************************************************/

#define TAG_SSID_NUMBER 0
#define TAG_PAYLOAD_NUMBER 221

#define PROBE_REQUEST_TYPE_SUBTYPE 0x0040
#define PROBE_REQSPONSE_TYPE_SUBTYPE 0x0050
#define PROBE_REQUEST_DURATION_ID 0x0
#define PROBE_RESPONSET_DURATION_ID 0x0
#define PROBE_REQUEST_PAYLOAD_LEN_MAX 255
#define BROADCAST_MAC_ADDR 0xFFFFFFFF

/* bull sdk definition of wifi ap info */
#define WIFI_SSID_LEN 32    // bull sdk definition WIFI SSID MAX LEN
#define WIFI_PASSWD_LEN 64  // bull sdk definition WIFI PASSWD MAX LEN

typedef struct
{
    unsigned char channel;                 ///< AP channel
    signed char rssi;                             ///< AP rssi
    unsigned char bssid[6];                ///< AP bssid
    unsigned char ssid[WIFI_SSID_LEN+1];   ///< AP ssid array
    unsigned char s_len;                   ///< AP ssid len
    unsigned char security;                //refer to WF_AP_AUTH_MODE_E
    unsigned char resv1;
	uint8_t data_len;
    uint8_t data[0];
}AP_IF_S;

typedef enum {
    COUNTRY_CODE_CN,
    COUNTRY_CODE_US,
    COUNTRY_CODE_JP,
    COUNTRY_CODE_EU
} COUNTRY_CODE_E;

/**
 * @brief WIFI芯片探测本地AP信息结构体
 * @struct MIMO_IF_S
 */
typedef enum
{
    MIMO_TYPE_NORMAL = 0,
    MIMO_TYPE_HT40,
    MIMO_TYPE_2X2,
    MIMO_TYPE_LDPC,

    MIMO_TYPE_NUM,
}MIMO_TYPE_E;

typedef struct
{
    signed char rssi;                /*!< MIMO包信号 */
    MIMO_TYPE_E type;                /*!< MIMO包类型 */
    unsigned short len;              /*!< MIMO包长度 */
    unsigned char channel;           /*!< MIMO包信道 */
    unsigned char mcs;
} MIMO_IF_S;

typedef enum {
    WFT_PROBE_REQ   = 0x40,     ///< Probe request
    WFT_PROBE_RSP   = 0x50,     ///< Probe response
    WFT_AUTH        = 0xB0,         //auth
    WFT_BEACON      = 0x80,     ///< Beacon
    WFT_DATA        = 0x08,     ///< Data
    WFT_QOS_DATA    = 0x88,     ///< QOS Data
    WFT_MIMO_DATA   = 0xff,     ///< MIMO Data
}WLAN_FRM_TP_E;


typedef struct {
    //802.11 management
    unsigned char id;
    unsigned char len;
    char data[0];   ///< data
} WLAN_MANAGEMENT_S;


typedef struct {
    unsigned char  frame_type;            ///< WLAN Frame type
    unsigned char  frame_ctrl_flags;      ///< Frame Control flags
    unsigned short duration;              ///< Duration
    unsigned char  dest[6];               ///< Destination MAC Address
    unsigned char  src[6];                ///< Source MAC Address
    unsigned char  bssid[6];              ///< BSSID MAC Address
    unsigned short seq_frag_num;          ///< Sequence and Fragmentation number
} WLAN_PROBE_REQ_IF_S;

typedef struct {
    unsigned char     frame_ctrl_flags;   ///< Frame Control flags
    unsigned short    duration;           ///< Duration
    unsigned char     dest[6];            ///< Destination MAC Address
    unsigned char     src[6];             ///< Source MAC Address
    unsigned char     bssid[6];           ///< BSSID MAC Address
    unsigned short    seq_frag_num;       ///< Sequence and Fragmentation number
    unsigned char     timestamp[8];       ///< Time stamp
    unsigned short    beacon_interval;    ///< Beacon Interval
    unsigned short    cap_info;           ///< Capability Information
    unsigned char     ssid_element_id;    ///< SSID Element ID
    unsigned char     ssid_len;           ///< SSID Length
    char        ssid[0];            ///< SSID
}WLAN_BEACON_IF_S;

#define TO_FROM_DS_MASK 0x03
#define TFD_IBSS 0x00           ///< da+sa+bssid
#define TFD_TO_AP 0x01          ///< bssid+sa+da
#define TFD_FROM_AP 0x02        ///< ds+bssid+sa
#define TFD_WDS 0x03            ///< ra+ta+da

typedef unsigned char BC_DA_CHAN_T;
#define BC_TO_AP 0
#define BC_FROM_AP 1
#define BC_CHAN_NUM 2

typedef struct {
    unsigned char addr1[6];
    unsigned char addr2[6];
    unsigned char addr3[6];
}WLAN_COM_ADDR_S;

typedef struct {
    unsigned char bssid[6];
    unsigned char src[6];
    unsigned char dst[6];
}WLAN_TO_AP_ADDR_S;

typedef struct {
    unsigned char dst[6];
    unsigned char bssid[6];
    unsigned char src[6];
}WLAN_FROM_AP_ADDR_S;

typedef union {
    WLAN_COM_ADDR_S com;
    WLAN_TO_AP_ADDR_S to_ap;
    WLAN_FROM_AP_ADDR_S from_ap;
}WLAN_ADDR_U;

typedef struct {
    unsigned char frame_ctrl_flags;   ///< Frame Control flags
    unsigned short duration;          ///< Duration
    WLAN_ADDR_U addr;                 ///< address
    unsigned short seq_frag_num;      ///< Sequence and Fragmentation number
    unsigned short qos_ctrl;          ///< QoS Control bits
}WLAN_DATA_IF_S;

/*!
\brief WLAN Frame info
\struct WLAN_FRAME_S
*/
typedef struct {
    unsigned char frame_type;                 ///< WLAN Frame type
    union {
        WLAN_BEACON_IF_S beacon_info;   ///< WLAN Beacon info
        WLAN_DATA_IF_S   data_info;     ///< WLAN Data info
        MIMO_IF_S        mimo_info;     ///< mimo info
    } frame_data;
}WLAN_FRAME_S,*P_WLAN_FRAME_S;

typedef struct
{
    unsigned short type_and_subtype;
    unsigned short duration_id;
    unsigned char addr1[6];
    unsigned char addr2[6];
    unsigned char addr3[6];
    unsigned short seq_ctrl;
} PROBE_REQUEST_PACKAGE_HEAD_S;

typedef struct
{
    uint16_t type_and_subtype;
    uint16_t duration_id;
    uint8_t addr1[6];
    uint8_t addr2[6];
    uint8_t addr3[6];
    uint16_t seq_ctrl;
    uint8_t timestamp[8]; // Time stamp
    uint16_t beacon_interval; // Beacon Interval
    uint16_t cap_info; // Capability Information
} PROBE_RESPONSE_PACKAGE_HEAD_S;


typedef struct
{
    unsigned char index;
    unsigned char len;
    unsigned char ptr[0];
} BEACON_TAG_DATA_UNIT_S;
#pragma pack()

typedef struct
{
    PROBE_REQUEST_PACKAGE_HEAD_S pack_head;
    BEACON_TAG_DATA_UNIT_S tag_ssid;
} PROBE_REQUEST_FIX_S;

/* tuya sdk definition of wifi function type */
typedef enum
{
    WF_STATION = 0,     ///< station type
    WF_AP,              ///< ap type
}WF_IF_E;

/* tuya sdk definition of wifi work mode */
typedef enum
{
    WWM_LOWPOWER = 0,   ///< wifi work in lowpower mode
    WWM_SNIFFER,        ///< wifi work in sniffer mode
    WWM_STATION,        ///< wifi work in station mode
    WWM_SOFTAP,         ///< wifi work in ap mode
    WWM_STATIONAP,      ///< wifi work in station+ap mode
    WWM_UNKNOWN,        ///< wifi work in unknown mode
}WF_WK_MD_E;

/* tuya sdk definition of wifi encryption type */
typedef enum
{
    WAAM_OPEN = 0,      ///< open
    WAAM_WEP,           ///< WEP
    WAAM_WPA_PSK,       ///< WPA—PSK
    WAAM_WPA2_PSK,      ///< WPA2—PSK
    WAAM_WPA_WPA2_PSK,  ///< WPA/WPA2
    WAAM_UNKNOWN,       //unknown
}WF_AP_AUTH_MODE_E;

/* tuya sdk definition of ap config info */
typedef struct {
    unsigned char ssid[WIFI_SSID_LEN+1];       ///< ssid
    unsigned char s_len;                       ///< len of ssid
    unsigned char passwd[WIFI_PASSWD_LEN+1];   ///< passwd
    unsigned char p_len;                       ///< len of passwd
    unsigned char chan;                        ///< channel. default:6
    WF_AP_AUTH_MODE_E md;                      ///< encryption type
    unsigned char ssid_hidden;                 ///< ssid hidden  default:0
    unsigned char max_conn;                    ///< max sta connect nums default:3
    unsigned short ms_interval;                ///< broadcast interval default:100
    NW_IP_S ip;                                ///< ip info for ap mode
}WF_AP_CFG_IF_S; 

/* tuya sdk definition of wifi station work status */
typedef enum {
    WSS_IDLE = 0,                       ///< not connected
    WSS_CONNECTING,                     ///< connecting wifi
    WSS_PASSWD_WRONG,                   ///< passwd not match
    WSS_NO_AP_FOUND,                    ///< ap is not found
    WSS_CONN_FAIL,                      ///< connect fail
    WSS_CONN_SUCCESS,                   ///< connect wifi success
    WSS_GOT_IP,                         ///< get ip success
}WF_STATION_STAT_E;


/* for fast connect*/
typedef struct {
    unsigned int len;                                                    ///< data len
    unsigned char data[0];                                                ///< data buff
}FAST_WF_CONNECTED_AP_INFO_V2_S;

/**
 * @brief callback function: SNIFFER_CALLBACK
 *        when wifi sniffers package from air, notify tuya-sdk
 *        with this callback. the package should include
 * @param[in]       buf         the buf wifi recv
 * @param[in]       len         the len of buf
 */
typedef void (*SNIFFER_CALLBACK)(CONST UINT8_T *buf, CONST UINT16_T len, CONST INT8_T rssi);

/**
 * @brief receive wifi management callback
 * 
 */
typedef void (*WIFI_REV_MGNT_CB)(UCHAR_T *buf, UINT_T len);

typedef void  (*BULL_WIFI_EVENT_SEND_T)(UINT_T event_id, PVOID_T param);

typedef enum{
    BULL_WIFI_EVENT_INIT = 0,
    BULL_WIFI_EVENT_START,
    BULL_WIFI_EVENT_CONNECTED,
    BULL_WIFI_EVENT_DISCONN,
    BULL_WIFI_EVENT_GOT_IP,
    BULL_WIFI_USER_EVENT
}BULL_WIFI_EVENT_ID_EUNM;

typedef struct {

	BULL_WIFI_EVENT_SEND_T event_cb;
    PVOID_T                param;
    CHAR_T                 evt_id_wifi_host_name;
	// CHAR_T              evt_id_wifi_sta_ready;
	// CHAR_T              evt_id_sacn_sta_done;
    // CHAR_T              evt_id_wifi_sta_start;    
    // CHAR_T              evt_id_wifi_sta_stop;  
    // CHAR_T              evt_id_wifi_sta_connected;  
    // CHAR_T              evt_id_wifi_sta_disconn;
}BULL_WIFI_REG_T;

/********************************************************************************
 *********************************bull_hal_drv_flash_intf******************************
 ********************************************************************************/
// 改
typedef enum {

    KV_FLASH_PART,
    OFFLINE_LOGS_PART,
    USER_DATA_PART,
    DOWLOAD_PART
}BULL_FLASH_PART_ENUM;

/********************************************************************************
 *********************************bull_hal_net_mqtt_intf*****************************
 ********************************************************************************/
typedef void*           MQTT_CLIENT_HANDLE;

typedef enum{
    BULL_MQTT_EVENT_ERROR = 0,
    BULL_MQTT_EVENT_CONNECTED,
    BULL_MQTT_EVENT_DISCONN,
    BULL_MQTT_EVENT_SUBSCRIBED,
    BULL_MQTT_EVENT_UNSUBSCRIBED,
    BULL_MQTT_EVENT_PUBLISHED,
    BULL_MQTT_EVENT_DATA,
    BULL_MQTT_EVENT_BEFORE_CONNECT,
    BULL_MQTT_EVENT_DELETED,
    BULL_MQTT_USER_EVENT
}BULL_MQTT_EVENT_ID_EUNM;

typedef struct 
{

    uint8_t qos;
    char *topic;
    uint16_t topic_len;
    uint8_t *payload;
    uint32_t payload_len;
}BULL_MQTT_RECEIVE_T;


/**
 * Topic definition struct
 */
typedef struct 
{
    const char *filter;  /*!< Topic filter  to subscribe */
    int qos; /*!< Max QoS level of the subscription */
} BULL_MQTT_TOPI_LIST_T;


typedef int (*MQTT_RECEIVE_DATA_CB)( BULL_MQTT_EVENT_ID_EUNM event_id, BULL_MQTT_RECEIVE_T *data, PVOID_T userata);


// 应用层调用的接收回调结构体
typedef struct
{
    MQTT_RECEIVE_DATA_CB rev_data_cb;
    PVOID_T              userdata;
}BULL_MQTT_RECEIVE_CB_T,*BULL_MQTT_RECEIVE_CB_P;

typedef struct
{

    const char *host;                       /*!< MQTT server domain (ipv4 as string) */
    const char *uri;                        /*!< Complete MQTT broker URI */
    uint32_t port;                          /*!< MQTT server port */
    const char *client_id;                  /*!< default client id is ``ESP32_%CHIPID%`` where %CHIPID% are last 3 bytes of MAC address in hex format */
    const char *username;                   /*!< MQTT username */
    const char *password;                   /*!< MQTT password */
    int keepalive;                          /*!< mqtt keepalive, default is 120 seconds */
    bool disable_auto_reconnect;            /*!< this mqtt client will reconnect to server (when errors/disconnect). Set disable_auto_reconnect=true to disable */
    int task_prio;                          /*!< MQTT task priority, default is 5, can be changed in ``make menuconfig`` */
    int task_stack;                         /*!< MQTT task stack size, default is 6144 bytes, can be changed in ``make menuconfig`` */
    int buffer_size;                        /*!< size of MQTT send/receive buffer, default is 1024 (only receive buffer size if ``out_buffer_size`` defined) */
    int refresh_connection_after_ms;        /*!< Refresh connection after this value (in milliseconds) */
    int reconnect_timeout_ms;               /*!< Reconnect to the broker after this value in miliseconds if auto reconnect is not disabled (defaults to 10s) */
    int out_buffer_size;                    /*!< size of MQTT output buffer. If not defined, both output and input buffers have the same size defined as ``buffer_size`` */
    bool disable_keepalive;                 /*!< Set disable_keepalive=true to turn off keep-alive mechanism, false by default (keepalive is active by default). Note: setting the config value `keepalive` to `0` doesn't disable keepalive feature, but uses a default keepalive period */
    BULL_MQTT_RECEIVE_CB_T rev_t;
}BULL_HAL_MQTT_REGISTER_T;


typedef struct {
    const char *filter;    /*!< Topic filter  to subscribe */
    int qos;              /*!< Max QoS level of the subscription */
} BULL_MQTT_TOPIC_T;


/********************************************************************************
 *********************************bull_hal_net_https_intf*****************************
 ********************************************************************************/
typedef void*           HTTPS_CLIENT_HANDLE;

typedef enum {
    BULL_HTTP_METHOD_GET = 0,    /*!< HTTP GET Method */
    BULL_HTTP_METHOD_POST,       /*!< HTTP POST Method */
    BULL_HTTP_METHOD_PUT,        /*!< HTTP PUT Method */
    BULL_HTTP_METHOD_PATCH,      /*!< HTTP PATCH Method */
    BULL_HTTP_METHOD_DELETE,     /*!< HTTP DELETE Method */
    BULL_HTTP_METHOD_HEAD,       /*!< HTTP HEAD Method */
    BULL_HTTP_METHOD_NOTIFY,     /*!< HTTP NOTIFY Method */
    BULL_HTTP_METHOD_SUBSCRIBE,  /*!< HTTP SUBSCRIBE Method */
    BULL_HTTP_METHOD_UNSUBSCRIBE,/*!< HTTP UNSUBSCRIBE Method */
    BULL_HTTP_METHOD_OPTIONS,    /*!< HTTP OPTIONS Method */
    BULL_HTTP_METHOD_MAX,
} BULL_HTTP_CLIENT_METHOD_EUNM;

typedef enum {
    BULL_HTTP_EVENT_ERROR = 0,       /*!< This event occurs when there are any errors during execution */
    BULL_HTTP_EVENT_ON_CONNECTED,    /*!< Once the HTTP has been connected to the server, no data exchange has been performed */
    BULL_HTTP_EVENT_HEADERS_SENT,     /*!< After sending all the headers to the server */
    BULL_HTTP_EVENT_HEADER_SENT = BULL_HTTP_EVENT_HEADERS_SENT, /*!< This header has been kept for backward compatability
                                                           and will be deprecated in future versions esp-idf */
    BULL_HTTP_EVENT_ON_HEADER,       /*!< Occurs when receiving each header sent from the server */
    BULL_HTTP_EVENT_ON_DATA,         /*!< Occurs when receiving data from the server, possibly multiple portions of the packet */
    BULL_HTTP_EVENT_ON_FINISH,       /*!< Occurs when finish a HTTP session */
    BULL_HTTP_EVENT_DISCONNECTED,    /*!< The connection has been disconnected */
    BULL_HTTP_EVENT_REDIRECT,        /*!< Intercepting HTTP redirects to handle them manually */
} BULL_HTTP_CLIENT_EVENT_ID_T;


typedef enum {
    /* 2xx - Success */
    BULL_HttpStatus_Ok                = 200,

    /* 3xx - Redirection */
    BULL_HttpStatus_MultipleChoices   = 300,
    BULL_HttpStatus_MovedPermanently  = 301,
    BULL_HttpStatus_Found             = 302,
    BULL_HttpStatus_SeeOther          = 303,
    BULL_HttpStatus_TemporaryRedirect = 307,
    BULL_HttpStatus_PermanentRedirect = 308,

    /* 4xx - Client Error */
    BULL_HttpStatus_BadRequest        = 400,
    BULL_HttpStatus_Unauthorized      = 401,
    BULL_HttpStatus_Forbidden         = 403,
    BULL_HttpStatus_NotFound          = 404,

    /* 5xx - Server Error */
    BULL_HttpStatus_InternalError     = 500
} BULL_HttpStatus_Code;

typedef VOID_T (*HTTPS_REV_DATA_CB)( BULL_HTTP_CLIENT_EVENT_ID_T event_id, UCHAR_T *data, UINT_T data_len, UINT_T total_len, PVOID_T userata );

typedef struct
{
    const char *                  url;  
    BULL_HTTP_CLIENT_METHOD_EUNM  method;
    HTTPS_REV_DATA_CB             data_recv_cb;                  //data reveive callback
    PVOID_T                       userata;
}BULL_HTTPS_REGISTER_T;

/********************************************************************************
 *********************************bull_hal_net_ntp_intf*****************************
 ********************************************************************************/


/// SNTP sync status
typedef enum {
    BULL_SNTP_SYNC_STATUS_RESET,         // Reset status.
    BULL_SNTP_SYNC_STATUS_COMPLETED,     // Time is synchronized.
    BULL_SNTP_SYNC_STATUS_IN_PROGRESS,   // Smooth time sync in progress.
} bull_sntp_sync_status_t;

/// SNTP operating modes per lwip SNTP module
typedef enum {
    BULL_SNTP_OPMODE_POLL,
    BULL_SNTP_OPMODE_LISTENONLY,
} bull_sntp_operatingmode_t;



#ifdef __cplusplus
}
#endif

#endif